package com.w3coffee.web.control;

import java.util.Collection;
import java.util.Comparator;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentSkipListSet;

import javax.servlet.ServletConfig;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.context.ApplicationContext;
import org.springframework.web.context.support.WebApplicationContextUtils;

import com.w3coffee.web.Branch;
import com.w3coffee.web.Util;
import com.w3coffee.web.dao.CoffeeDao;
import com.w3coffee.web.dao.model.TBranch;
import com.w3coffee.web.dao.model.TMeal;
import com.w3coffee.web.dao.model.TNews;

public class ContextServlet extends HttpServlet {
	private static final long serialVersionUID = 4696241987867918961L;

	private static ApplicationContext appContext = null;
	/** 3WCoffee分支机构表 */
	private static Map<Integer, Branch> branchs;
	/** 餐点 */
	private static Map<Integer, TMeal> meals;
	/** 3WCoffee新闻缓存 */
	private static NewsManager newsManager;

	private static Config config;
	private static CoffeeDao dao;
	private Logger logger = LoggerFactory.getLogger(getClass());

	@Override
	public void init(ServletConfig servletConfig) throws ServletException {
		

		appContext = WebApplicationContextUtils
				.getRequiredWebApplicationContext(servletConfig
						.getServletContext());
		dao = (CoffeeDao) getBean("coffeeDao");
		config = (Config) getBean("config");

		logger.info("Loading all branchs information...");
		loadBranchs();
		
		logger.info("Loading all meals information...");
		loadMeals();

		logger.info("Loading cached news...");
		loadNews();
	}

	public static Object getBean(String beanName) {
		return appContext.getBean(beanName);
	}

	private void loadBranchs() {
		branchs = new ConcurrentHashMap<Integer, Branch>();
		try {
			List<TBranch> allBranches = dao.getAllBranchs();
			for (TBranch tb : allBranches) {
				branchs.put(tb.getId(), new Branch(tb));
			}
		} catch (Exception e) {
			logger.error("Load all branchs information error.", e);
		}
	}
	
	private void loadMeals() {
		meals = new ConcurrentHashMap<Integer, TMeal>();
		try {
			List<TMeal> allMeals = dao.getAllMeals();
			for (TMeal m : allMeals) {
				meals.put(m.getId(), m);
			}
		} catch (Exception e) {
			logger.error("Load all branchs information error.", e);
		}
	}

	private void loadNews() {
		try {
			newsManager = new NewsManager(dao, config.getCachedNewsNumber());
		} catch (Exception e) {
			logger.error("Load cached news error.", e);
		}
	}
	
	public static Collection<TNews> getNews() {
		return newsManager.getNews();
	}
	
	public static TNews getNews(int id) {
		return newsManager.getNews(id);
	}
	
	public static Collection<TMeal> getMeals() {
		return meals.values();
	}

	public static Branch getBranch(double lng, double lat, double acy) {
		double distance, error;

		for (Branch branch : branchs.values()) {
			distance = Util.getDistance(branch.getLongitude(),
					branch.getLatitude(), lng, lat);
			error = acy + branch.getAccuracy();

			System.out.println("lng=" + lng + " lat=" + lat + " branchLng="
					+ branch.getLongitude() + " branchLat="
					+ branch.getLatitude());
			System.out.println("distance=" + distance);
			System.out.println("error=" + error);

			if (Math.abs(distance) < (1000 + error)) {
				System.out.println(branch.getName());
				return branch;
			}
		}

		return null;
	}

	public static Branch getBranch(int bid) {
		return branchs.get(bid);
	}

	public static CoffeeDao getDao() {
		return (CoffeeDao) getBean("coffeeDao");
	}

	public static Config getConfig() {
		return (Config) getBean("config");
	}

}
